#ifndef WINDOW6_H
#define WINDOW6_H

#include <QMainWindow>
#include <QThread>
#include <QPushButton>
#include <QProgressBar>
#include <QProgressBar>
#include <QThreadPool>
#include "mythread.h"
#include "myrunnable.h"
/**
线程池
当线程的任务量比较大时，频繁创建和销毁线程会有很大的内存开销，此时使用QThread的方法就不合适，
应该使用线程池QThreadPool。QThread适用于常驻内存的任务，QThreadPool适用于不常驻内存，任务量比较大的情况。

QRunnable 是一个非常轻量的抽象类，它的主体是纯虚函数 QRunnable::run()，我们需要继承它并实现这个函数。
使用时需要将其子类的实例放进 QThreadPool 的执行队列，线程池默认会在运行后自动删除这个实例。
每一个Qt程序都有一个全局的线程池，我们可以直接使用它，这就不需要手动创建和管理线程池，
调用QThreadPool::globalInstance()得到，可在多个类中共同使用一个线程池。它默认最多创建 8 个线程，
如果想改变最大线程数则调用 setMaxThreadCount() 进行修改，调用 activeThreadCount() 查看线程池中当前活跃的线程数。

Qt并不是推荐使用其全局线程池，何况实际的项目当中我们通常并不希望仅仅使用一个全局的线程池
，而是在需要线程池的工程中都构建和维护自己一个小小的线程池。
用QThreadPool pool的方式建立一个局部线程池，并由当前类维护，可保证此线程池仅供当前类应用。

常规使用
定一个任务类例如叫 Task，继承 QRunnable 并实现虚函数 run()，Task 的对象作为 QThreadPool::start() 的参数就可以了，
线程池会自动的在线程中调用 Task 的 run() 函数，异步执行。线程池中的 QRunnable 对象太多时并不会立即为每一个
 QRunnable 对象创建一个线程，而是让它们排队执行，同时最多有 maxThreadCount() 个线程并行执行。

 程序当中QRunnable是以指针的形式创建的，是QThreadPool在运行完线程后自动释放，官方文档有一句：
    QThreadPool takes ownership and deletes QRunnable object automatically，这也是Qt半自动内存回收机制的一方面。

SIGNAL/SLOT 实现线程池与外界通信:
QRunnable 不是 QObject的子类，无法使用信号与槽的机制与外界通信的手段。实现与外界通信有两种方法：
1. 子类采用QObejct 和 QRunnable多重继承，而且QObject要放在前面，再用信号与槽的机制。
2. 使用QMetaObject::invokeMethod。
 */
class Window6 : public QMainWindow
{
    Q_OBJECT
public:
    explicit Window6(QWidget *parent = nullptr);

    //使用线程
    void threadTest();
    //使用线程池
    void threadPoolTest();
signals:

public slots:
    //开启线程
    void slotStartThread();
    //停止线程
    void slotStopThread();
    //回收线程对象资源
    void slotDeleteThread();

    void startFun();
    //接收runnable传过来的值
    void slotReceiveProcess(int);
private:
    QPushButton * startThreadBtn;//开启线程按钮
    QPushButton * stopThreadBtn; //停止线程按钮
    MyThread * myThread = nullptr;

    QPushButton *startButton;
    QProgressBar *progressBar;
    QProgressBar *progressBar2;

    //线程池
    QThreadPool * threadPool = nullptr;

};

#endif // WINDOW6_H
